import 'dart:io';

import 'package:flutter/material.dart';
import 'package:fluttercommon/src/pickers/preview_photo.dart';

import '../extentions/build_context_extentions.dart';

typedef Future<String?> PickPhotoLocalPath(BuildContext context);

class PickMultiPhotoWidget extends StatefulWidget {
  final int maxCount;
  final int crossAxisCount;

  final Widget placeholder;
  final PickPhotoLocalPath pickPhoto;
  final double childAspectRatio;
  final double borderRadius;
  final ValueChanged<List<String>>? onImageChanged;

  PickMultiPhotoWidget({
    Key? key,
    this.maxCount = 9,
    this.crossAxisCount = 3,
    this.childAspectRatio = 1.0,
    this.borderRadius = 4.0,
    required this.placeholder,
    required this.pickPhoto,
    this.onImageChanged,
  }) : super(key: key);

  @override
  _PickMultiPhotoWidgetState createState() => _PickMultiPhotoWidgetState();
}

class _PickMultiPhotoWidgetState extends State<PickMultiPhotoWidget> {
  static const addNewItemPlaceholder = "PLACEHOLDER";
  List<String> fileLocalPathList = [addNewItemPlaceholder];

  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: widget.crossAxisCount,
      shrinkWrap: true,
      mainAxisSpacing: 8,
      crossAxisSpacing: 8,
      childAspectRatio: widget.childAspectRatio,
      physics: NeverScrollableScrollPhysics(),
      children: [
        for (final String path in fileLocalPathList) buildItem(context, path),
      ],
    );
  }

  Widget buildItem(BuildContext context, String path) {
    if (path == addNewItemPlaceholder)
      return InkWell(
        child: widget.placeholder,
        onTap: pickNewItem,
      );
    return InkWell(
      child: ClipRRect(
        borderRadius: BorderRadius.circular(widget.borderRadius),
        child: Image.file(
          File(path),
          fit: BoxFit.cover,
        ),
      ),
      onTap: () {
        previewItems(path);
      },
    );
  }

  Future pickNewItem() async {
    final path = await widget.pickPhoto(context);
    if (path != null) {
      setState(() {
        fileLocalPathList.insert(fileLocalPathList.length - 1, path);
        if (fileLocalPathList.length > widget.maxCount) {
          fileLocalPathList.removeLast();
        }
        notifyImageChanged();
      });
    }
  }

  void notifyImageChanged() {
    widget.onImageChanged?.call(fileLocalPathList
        .where((element) => element != addNewItemPlaceholder)
        .toList());
  }

  void previewItems(String current) async {
    final photos = fileLocalPathList
        .where((element) => element != addNewItemPlaceholder)
        .toList();
    final result = await context.goto<List<String>>(
        PreviewPhotosPage(photos: photos, initial: current));
    setState(() {
      if (result == null || result.isEmpty) {
        fileLocalPathList
          ..clear()
          ..add(addNewItemPlaceholder);
      } else if (photos.length != result.length) {
        fileLocalPathList
          ..clear()
          ..addAll(result)
          ..add(addNewItemPlaceholder);
      }
      notifyImageChanged();
    });
  }
}
